package com.song.tools.songtest.service.impl;

import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
import com.song.tools.core.exception.BusinessException;
import com.song.tools.core.exception.ExceptionCodeEnum;
import com.song.tools.core.util.ObjectUtils;
import com.song.tools.mvc.request.BatchIdRequest;
import com.song.tools.mvc.request.PageRequest;
import com.song.tools.mvc.response.DeleteResponse;
import com.song.tools.mvc.response.PageResponse;
import com.song.tools.mvc.validator.ValidationException;
import com.song.tools.mvc.validator.ValidationResult;
import com.song.tools.songtest.beans.bo.SysRoleUserBo;
import com.song.tools.songtest.beans.query.SysRoleUserQuery;
import com.song.tools.songtest.beans.request.SysRoleUserQueryRequest;
import com.song.tools.songtest.beans.request.SysRoleUserSaveRequest;
import com.song.tools.songtest.beans.request.SysRoleUserUpdateRequest;
import com.song.tools.songtest.beans.response.SysRoleUserDeleteResponse;
import com.song.tools.songtest.beans.response.SysRoleUserQueryResponse;
import com.song.tools.songtest.beans.response.SysRoleUserSaveResponse;
import com.song.tools.songtest.beans.response.SysRoleUserUpdateResponse;
import com.song.tools.songtest.convertor.SysRoleUserConvertor;
import com.song.tools.songtest.dao.entity.SysRoleUser;
import com.song.tools.songtest.manager.SysRoleUserManager;
import com.song.tools.songtest.service.SysRoleUserService;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * <p>
 * 用户角色关系表 服务实现类
 * </p>
 *
 * @author song tools
 * @since 2024-07-12
 */
@Slf4j
@Service
public class SysRoleUserServiceImpl implements SysRoleUserService {

    @Resource
    private SysRoleUserManager sysRoleUserManager;

    @Resource
    private SysRoleUserConvertor sysRoleUserConvertor;

    private static final Map<String, SFunction<SysRoleUser, ?>> COLUMNS_FUNCTION_MAP;

    static {
        COLUMNS_FUNCTION_MAP = Map.of(
                "id", SysRoleUser::getId
        );
    }


    /**
     * 通过主键列表批量删除
     *
     * @param request 主键列表请求体
     * @return 删除结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public SysRoleUserDeleteResponse deleteByPrimaryKeys(BatchIdRequest<Long> request) {
        List<Long> primaryKeys = request.getIds();
        if (CollUtil.isEmpty(primaryKeys)) {
            throw new BusinessException(ExceptionCodeEnum.PARAM_NOT_NULL);
        }

        // 如果列表很大，考虑分批删除以减轻数据库压力
        int batchSize = 100; // 每批处理100条
        int totalDeleted = 0; // 记录总共删除的行数

        for (int i = 0; i < primaryKeys.size(); i += batchSize) {
            int toIndex = Math.min(i + batchSize, primaryKeys.size());
            List<Long> batchKeys = primaryKeys.subList(i, toIndex);

            int rows = sysRoleUserManager.deleteBatchByPrimaryKeys(batchKeys);
            totalDeleted += rows;
        }

        SysRoleUserDeleteResponse response = new SysRoleUserDeleteResponse();
        response.setDeleted(totalDeleted > 0 ? DeleteResponse.DELETED_SUCCESS : DeleteResponse.DELETED_FAIL);
        return response;
    }


    /**
     * 通过唯一key查询单个数据
     *
     * @param uniqueKey 唯一键
     * @param column    列名
     * @return 单个数据查询响应结果
     */
    @Override
    public SysRoleUserQueryResponse getOneByUniqueKey(Object uniqueKey, String column) {
        // 根据业务ID查询
        SysRoleUserBo sysRoleUserBo = sysRoleUserManager.getOneByUniqueKey(uniqueKey, COLUMNS_FUNCTION_MAP.getOrDefault(column, SysRoleUser::getId));
        return sysRoleUserConvertor.entityBoToQueryResponse(sysRoleUserBo);
    }

    /**
     * 查询信息（不分页）
     *
     * @param request 请求
     * @return 响应
     */
    @Override
    public List<SysRoleUserQueryResponse> list(SysRoleUserQueryRequest request) {
        SysRoleUserQuery sysRoleUserQuery = sysRoleUserConvertor.queryRequestToQuery(request);
        if (ObjectUtils.isNotEmpty(sysRoleUserQuery)) {
            List<SysRoleUserBo> sysRoleUserList = sysRoleUserManager.list(sysRoleUserQuery);
            if (ObjectUtils.isNotEmpty(sysRoleUserList)) {
                return sysRoleUserList.stream()
                        .map(sysRoleUserConvertor::entityBoToQueryResponse)
                        .filter(ObjectUtils::isNotEmpty)
                        .collect(Collectors.toList());
            }
        }
        return Collections.emptyList();
    }


    /**
     * 查询信息（分页）
     *
     * @param request 请求
     * @return PageResponse 响应
     */
    @Override
    public PageResponse<SysRoleUserQueryResponse> listPages(PageRequest<SysRoleUserQueryRequest> request) {
        try {
            // 分页查询
            IPage<SysRoleUserBo> sysRoleUserPage = sysRoleUserManager.page(transformToQuery(request));

            // 安全地处理分页转换逻辑
            return safelyConvertPage(sysRoleUserPage);
        } catch (Exception e) {
            log.error("查询失败", e);
            throw new BusinessException(ExceptionCodeEnum.SELECT_ERROR);
        }
    }


    /**
     * 安全地将分页数据转换为响应对象
     *
     * @param sysRoleUserPage 分页查询结果
     * @return 分页响应对象
     */
    private PageResponse<SysRoleUserQueryResponse> safelyConvertPage(IPage<SysRoleUserBo> sysRoleUserPage) {
        if (sysRoleUserPage == null || sysRoleUserPage.getRecords() == null) {
            return new PageResponse<>();
        }

        // 使用并行流进行转换以提高效率，但需确保线程安全
        List<SysRoleUserQueryResponse> responses = sysRoleUserPage.getRecords().parallelStream()
                .map(sysRoleUserBo -> sysRoleUserConvertor.entityBoToQueryResponse(sysRoleUserBo))
                .collect(Collectors.toList());

        return PageResponse.convertPage(sysRoleUserPage, responses);
    }


    /**
     * 将请求 request 转换成 manager 的 query 对象
     *
     * @param request 请求参数
     * @return query 对象
     */
    private PageRequest<SysRoleUserQuery> transformToQuery(PageRequest<SysRoleUserQueryRequest> request) {
        SysRoleUserQuery sysRoleUserQuery = sysRoleUserConvertor.queryRequestToQuery(request.getData());
        return new PageRequest<>(request.getPageNum(), request.getPageSize(), sysRoleUserQuery);
    }


    /**
     * 新增
     *
     * @param saveRequest 请求入参
     * @return 响应
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public SysRoleUserSaveResponse save(SysRoleUserSaveRequest saveRequest) {
        // 校验请求入参
        ValidationResult validationResult = validateOnSave(saveRequest);
        if (!validationResult.isValid()) {
            throw ValidationException.message(validationResult.getErrorMessage());
        }

        // 根据入参封装 BO对象
        SysRoleUserBo sysRoleUserBo = sysRoleUserConvertor.saveRequestToEntityBo(saveRequest);

        // 数据库操作：插入数据
        int rows = sysRoleUserManager.save(sysRoleUserBo);

        // 处理插入结果
        boolean saveSuccess = rows > 0;
        // 新增数据成功，返回结果
        if (saveSuccess) {
            // 修改后的数据通过数据库查询返回
            SysRoleUserBo savedSysRoleUserBo = sysRoleUserManager.getOneByUniqueKey(sysRoleUserBo.getId(), SysRoleUser::getId);
            return sysRoleUserConvertor.entityBoToSaveResponse(savedSysRoleUserBo);
        }

        // 新增数据失败，抛出异常
        throw new BusinessException(ExceptionCodeEnum.CREATE_ERROR);
    }

    /**
     * 修改
     *
     * @param updateRequest 请求
     * @return 响应
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public SysRoleUserUpdateResponse update(SysRoleUserUpdateRequest updateRequest) {
        // 校验请求入参
        ValidationResult validationResult = validateOnUpdate(updateRequest);
        if (!validationResult.isValid()) {
            throw ValidationException.message(validationResult.getErrorMessage());
        }

        // 根据入参封装 BO对象
        SysRoleUserBo sysRoleUserBo = sysRoleUserConvertor.updateRequestToEntityBo(updateRequest);

        // 数据库操作：修改数据
        int rows = sysRoleUserManager.updateByPrimaryKey(sysRoleUserBo);

        // 处理修改结果
        boolean updateSuccess = rows > 0;
        // 修改数据成功，返回结果
        if (updateSuccess) {
            // 修改后的数据通过数据库查询返回
            SysRoleUserBo updatedSysRoleUserBo = sysRoleUserManager.getOneByUniqueKey(sysRoleUserBo.getId(), SysRoleUser::getId);
            return sysRoleUserConvertor.entityBoToUpdateResponse(updatedSysRoleUserBo);
        }

        // 修改数据失败，抛出异常
        throw new BusinessException(ExceptionCodeEnum.UPDATE_ERROR);
    }
}
